#include "LogicUnionModule.h"
#include "LogicActivityModule.h"
#include "LogicService.h"

#include "base/core/com_define.h"
#include "base/core/os/time.h"
#include "base/core/Profiler.h"
#include "base/core/gamemath.h"
#include "Common/Utility/ServerTime.h"
#include "ProtoBuffer/AllProtocol.h"
#include "Access/CharacterDataSet.h"
#include "Character/PlayerMgr.h"
#include "Common/Utility/AccountUtility.h"
#include "Common/TableDataEx/UnionCfg.h"
#include "Duplicate/DuplicateMgr.h"
#include "Common/UnionDefine.h"
#include "Common/TableData/GuildSupplyCfg.h"
#include "Character/drop/DropMgr.h"
#include "Common/TableDataEx/DuplicateCfg.h"

#ifdef _MSC_VER
#pragma warning(disable:4100)
#pragma warning(disable:4244)
#pragma warning(disable:4102)
#endif

using namespace ProtoBuf;

LogicUnionModule::LogicUnionModule()
{}

LogicUnionModule::~LogicUnionModule()
{}


bool LogicUnionModule::Init()
{
	IMessageDispatch *pMessageDispatch = g_GetLogicService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return false;
	}
	pMessageDispatch->registerServerHandler(EMODULE_ID_UNION, this);
	pMessageDispatch->registerClientHandler(EMODULE_ID_UNION, this);

	return true;
}

void LogicUnionModule::UnInit()
{
	IMessageDispatch *pMessageDispatch = g_GetLogicService()->GetServiceMessageDispatch();
	if (nullptr != pMessageDispatch)
	{
		pMessageDispatch->unregisterServerHandler(EMODULE_ID_UNION);
		pMessageDispatch->unregisterClientHandler(EMODULE_ID_UNION);
	}
	
}

void LogicUnionModule::onClientMessage(uint32_t actionId, RECV_PACKAGE &package, uint64_t Id /*= 0*/)
{
	switch (actionId)
	{
	case CLIENT_TO_CENTER_CREATE_UNION:
		{
			Create(Id, package);
		}
		break;
	default:
		break;
	}
}

void LogicUnionModule::onServerMessage(uint32_t actionId, RECV_PACKAGE &package)
{
	_UNUSE(package);
	switch (actionId)
	{
	case CENTER_TO_LOGIC_UNION_CREATE:
		{
			CLCreate(package);
		}
		break;
	case CENTER_TO_LOGIC_CHAR_UNION_UPDATE:
		{
			CLCharUnionUpdate(package);
		}
		break;
	case CENTER_TO_LOGIC_UNION_DISMISS:
		{
			CLUnionDismiss(package);
		}
		break;
	case CENTER_TO_LOGIC_UNION_KICK_MEM:
		{
			CLUnionKickMem(package);
		}
		break;
	case CENTER_TO_LOGIC_UNION_FETCH_SCORE:
		{
			CLUnionFetchScore(package);
		}
		break;
	case CENTER_TO_LOGIC_UNION_HOME_SCENE_BIND:
		{
			CLBindUnionHomeScene(package);
		}
		break;
	case CENTER_TO_LOGIC_UNION_ACTIVITY_STATE:
		{
			CLUnionActivityState(package);
		}
		break;
	case CENTER_TO_LOGIC_UNION_LEVEL_UPDATE:
		{
			CLUnionLevUpdate(package);
		}
		break;
	/*case CENTER_TO_LOGIC_UNION_MAKE_UP_VERIFY:	//废弃
		{
			CLUnionMakeUp(package);
		}
		break;*/
	case CENTER_TO_LOGIC_UNION_FIGHT_UP_VERIFY:
		{
			CLUnionFightUp(package);
		}
		break;
	case CENTER_TO_LOGIC_UNION_LEADER_FACADE_NOTIFY:
		{
			CLUnionLeaderFacade(package);
		}
		break;
	case CENTER_TO_LOGIC_UNION_DUNGEON_CLOSE:
		{
			CLUnionDungeonClose(package);
		}
		break;
	default:
		break;
	}
}

void LogicUnionModule::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	_UNUSE(nSrcID);
	_UNUSE(bySrcType);
	_UNUSE(pContext);
	_UNUSE(pContext);
	_UNUSE(nLen);
	switch (nEventID)
	{
	case 1:
		break;
	default:
		break;
	}
}

void LogicUnionModule::Create(CharIDType charId, RECV_PACKAGE &package)
{
	Union_CreateReq req;
	if (!req.ParseFromArray(package.dataAfterHead,package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] Union_CreateReq parse failed...");
		return;
	}
	const GuildConstantCfgInfo *pConstCfg = g_GetUnionCfgMgr()->GetUnionInitCfgInfo();
	if (nullptr == pConstCfg)
	{
		LogErrFmtPrint("[logic] nullptr == pConstCfg....charid:%llu ", charId);
		return;
	}
	Player *pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("[logic] nullptr == pPlayer....charid:%llu ", charId);
		return;
	}
	if (ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState())
	{
		LogErrFmtPrint("[logic] LogicUnionModule::Create...ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState()....cid:%lu,zid:%d,id:%d ", charId, g_GetLogicService()->GetZID(), g_GetLogicService()->GetID());
		return;
	}
	Part *pPackage = pPlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		LogErrFmtPrint("[logic] nullptr == pPackage....charid:%llu ", charId);
		return;
	}	
	SItemSourceParam sourceParam;
	sourceParam.source = S_UNION;
	if (pPlayer->GetAttr(C_UNION_ID) > 0)
	{
		//已经加入工会
		Union_CreateRsp rsp;
		rsp.set_retcode(RET_UNION_ALREADY_JOIN);
		g_GetLogicService()->SendDataToClient(charId, EMODULE_ID_UNION, CENTER_TO_CLIENT_CREATE_UNION, &rsp);
	}
	else if (!pPackage->RemoveItem(pConstCfg->setItem, 1, sourceParam)) //这里先扣除物品
	{
		//道具不够
		Union_CreateRsp rsp;
		rsp.set_retcode(RET_UNION_CREATE_ITEM_LACK);
		g_GetLogicService()->SendDataToClient(charId, EMODULE_ID_UNION, CENTER_TO_CLIENT_CREATE_UNION, &rsp);
	}
	else
	{
		LC_UnionCreateReq reqCenter;
		reqCenter.set_charid(charId);
		reqCenter.set_icon_id(req.icon_id());
		reqCenter.set_name(req.name());
		reqCenter.set_notice(req.notice());
		if (!g_GetLogicService()->SendDataToCenter(EMODULE_ID_UNION, LOGIC_TO_CENTER_UNION_CREATE, &reqCenter))
		{
			//先扣除道具,中心服创建失败了在归还
			pPackage->AddItem(pConstCfg->setItem, 1, sourceParam);
		}
	}

}

void LogicUnionModule::CLCreate(RECV_PACKAGE &package)
{
	CL_UnionCreateRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionCreateRsp parse failed...");
		return;
	}
	CharIDType charId = rsp.charid();
	const GuildConstantCfgInfo *pConstCfg = g_GetUnionCfgMgr()->GetUnionInitCfgInfo();
	if (nullptr == pConstCfg)
	{
		LogErrFmtPrint("[logic] LogicUnionModule::CLCreate....nullptr == pConstCfg...charid:%lu ", charId);
		return;
	}	
	Player *pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("[logic] LogicUnionModule::CLCreate....nullptr == pPlayer...charid:%lu,item:%u ", charId, pConstCfg->setItem);
		return;
	}
	
	if (ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState())
	{
		LogErrFmtPrint("[logic] LogicUnionModule::CLCreate...ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState()....cid:%lu,zid:%d,id:%d,item:%u ", charId, g_GetLogicService()->GetZID(), g_GetLogicService()->GetID(), pConstCfg->setItem);
		return;
	}
	
	Part *pPackage = pPlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		LogErrFmtPrint("[logic] LogicUnionModule::CLCreate....nullptr == pPackage...charid:%lu ", charId);
		return;
	}
	
	//创建工会失败，归还事先扣除的物品
	SItemSourceParam sourceParam;
	sourceParam.source = S_UNION;
	if (!pPackage->AddItem(pConstCfg->setItem, 1, sourceParam))
	{
		LogErrFmtPrint("[logic] LogicUnionModule::CLCreate....pPackage->AddItem failed...charid:%lu ", charId);
	}
}

void LogicUnionModule::CLCharUnionUpdate(RECV_PACKAGE &package)
{
	CL_UnionCharUpdateRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionCharUpdateRsp parse failed...");
		return;
	}
	CharIDType charId = rsp.charid();
	Player *pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr == pPlayer)
	{
		//LogErrFmtPrint("[logic] LogicUnionModule::CLCharUnionUpdate....nullptr == pPlayer...charid:%llu ", charId);
		return;
	}
	LogDebugFmtPrint("CLCharUnionUpdate...cid:%lu,unionid:%u,name:%s,duty:%d,level:%d,icon:%d,contri:%d,officelev:%d,vaultlev:%d,homescene:%u ", charId, rsp.union_id(), rsp.union_name().c_str(), rsp.union_duty(), rsp.union_level(), rsp.union_icon(), rsp.union_contri(), rsp.office_level(), rsp.vault_level(), rsp.union_home_scene());
	//
	int32_t oldUnionId = pPlayer->GetAttr(C_UNION_ID);
	pPlayer->SetUnionAttr(rsp.union_id(), rsp.union_name(), rsp.union_duty(), rsp.union_level(), rsp.union_icon(), rsp.union_contri(), rsp.office_level(),rsp.vault_level(),rsp.union_home_scene(),true);
	if (oldUnionId != (int32_t)pPlayer->GetAttr(C_UNION_ID))
	{
		//工会有变动  CuildChangeEvent
		CuildChangeEvent changeEvent;
		changeEvent.level = rsp.union_level();
		g_GetEvent()->FireExecute(EVENT_GUILD_CHANGE, pPlayer->GetCid(), pPlayer->CreatureKind(), &changeEvent, sizeof(changeEvent));
	}
	//加入公会
	if (oldUnionId == 0 && pPlayer->GetAttr(C_UNION_ID) > 0)
	{
		g_GetGActivityMgr()->OnJoinUnion(pPlayer);
	}
	//退出公会
	if (oldUnionId > 0 && pPlayer->GetAttr(C_UNION_ID) <= 0)
	{
		g_GetGActivityMgr()->OnQuitUnion(pPlayer);
	}

	//历史公会贡献
	UnionHistoryContriEvent contriChangeEvent;
	contriChangeEvent.value = rsp.history_contri();
	g_GetEvent()->FireExecute(EVENT_UNION_HISTORY_CONTRI, pPlayer->GetCid(), pPlayer->CreatureKind(), &contriChangeEvent, sizeof(contriChangeEvent));
}

void LogicUnionModule::CLUnionDismiss(RECV_PACKAGE &package)
{
	CL_UnionDismissRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionDismissRsp parse failed...");
		return;
	}
	//
	uint32_t unionId = rsp.union_id();
	uint32_t sceneId = rsp.scene_id();
	LogDebugFmtPrint("[logic] LogicUnionModule::CLUnionDismiss...unionId:%u ,sceneId:%u ",unionId,sceneId);
	//
	g_GetDuplicateMgr()->OnUnionDismiss(unionId, sceneId);
}

void LogicUnionModule::CLUnionKickMem(RECV_PACKAGE &package)
{
	CL_UnionKickMemRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionKickMemRsp parse failed...");
		return;
	}
	//
	CharIDType charId = rsp.char_id();
	uint32_t sceneId = rsp.scene_id();
	LogDebugFmtPrint("[logic] LogicUnionModule::CLUnionKickMem...charid:%llu ,sceneId:%u ", charId, sceneId);
	//
	g_GetDuplicateMgr()->OnUnionKickMem(charId, sceneId);
}

void LogicUnionModule::CLUnionFetchScore(RECV_PACKAGE &package)
{
	CL_UnionFetchScoreRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionFetchScoreRsp parse failed...");
		return;
	}
	CharIDType charId = rsp.char_id();
	uint32_t boxId = rsp.box_id();
	VEC_INT32 vecBox;
	vecBox.clear();
	vecBox.push_back(boxId);
	int32_t ret = RET_FAIL;
	Player *pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr != pPlayer)
	{
		if (ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState()) //如果是切换逻辑节点，这个时候玩家数据已经带到中心服去了，这里直接领取失败
		{
			LogErrFmtPrint("[logic] CLUnionFetchScore...ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState()....cid:%lu,zid:%d,id:%d,boxId:%u ", charId, g_GetLogicService()->GetZID(), g_GetLogicService()->GetID(), boxId);
		}
		else
		{
			SItemSourceParam sourceParam;
			sourceParam.notifySource = ENotifyType_Item_Cloud;
			ret = g_GetDropMgr()->PlayerAddBox(pPlayer, vecBox, sourceParam);
			if (RET_SUCCESS == ret)
			{
				//领取奖励成功，完成云端试练活动
				g_GetGActivityMgr()->OnFinishActivity(g_GetDuplicateCfgMgr()->GetCloudActId(), charId);
			}
		}		
	}
	else
	{
		ret = RET_FAIL;
	}
	LC_UnionFetchScoreFailedRsp centerRsp;
	centerRsp.set_retcode(ret);
	centerRsp.set_char_id(charId);
	g_GetLogicService()->SendDataToCenter(EMODULE_ID_UNION, LOGIC_TO_CENTER_UNION_FETCH_SCORE_RESULT, &centerRsp);
}

void LogicUnionModule::CLBindUnionHomeScene(RECV_PACKAGE &package)
{
	CL_UnionCreateHomeRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionCreateHomeRsp parse failed...");
		return;
	}
	uint32_t unionId = rsp.union_id();
	uint32_t sceneId = rsp.scene_id();
	g_GetDuplicateMgr()->OnBindUnionHome(unionId,sceneId);
}


void LogicUnionModule::CLUnionActivityState(RECV_PACKAGE &package)
{
	CL_UnionActivityStateRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionActivityStateRsp parse failed...");
		return;
	}
	SUnionActParam param;
	param.actScene = rsp.scene_id();
	param.averageLev = rsp.average_level();
	param.collegeLev = rsp.college_level();
	param.unionId = rsp.union_id();
	param.vaultLev = rsp.vault_level();
	int32_t state = rsp.state();
	uint32_t actId = rsp.activity_id();
	g_GetDuplicateMgr()->OnUnionActivityState(actId,state,param);
}

void LogicUnionModule::CLUnionLevUpdate(RECV_PACKAGE &package)
{
	CL_UnionLevUpdateRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionLevUpdateRsp parse failed...");
		return;
	}
	uint32_t unionId = rsp.union_id();
	uint32_t sceneId = rsp.scene_id();
	int32_t level = rsp.union_lev();
	g_GetDuplicateMgr()->OnUnionLevel(unionId, sceneId, level);
}

void LogicUnionModule::CLUnionFightUp(RECV_PACKAGE &package)
{
	CL_UnionFightUpVerifyRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionFightUpVerifyRsp parse failed...");
		return;
	}
	Player *pPlayer = g_GetCreatureMgr()->GetPlayer(rsp.char_id());
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("[logic] CL_UnionFightUpVerifyRsp parse..nullptr == pPlayer... failed...cid:%lu ", rsp.char_id());
		return;
	}
	if (ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState())
	{
		LogErrFmtPrint("[logic] CL_UnionFightUpVerifyRsp ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState()...cid:lu ", rsp.char_id());
		return;
	}
	DeputyPart *pPart = dynamic_cast<DeputyPart*>(pPlayer->GetPart(PART_DEPUTY));
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] CL_UnionFightUpVerifyRsp parse..nullptr == pPart... failed...");
		return;
	}
	pPart->FightUpgrade_VerifyReturn(rsp);
}

void LogicUnionModule::CLUnionMakeUp(RECV_PACKAGE &package)
{
	CL_UnionMakeUpVerifyRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionMakeUpVerifyRsp parse failed...");
		return;
	}
	Player *pPlayer = g_GetCreatureMgr()->GetPlayer(rsp.char_id());
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("[logic] CL_UnionMakeUpVerifyRsp parse..nullptr == pPlayer... failed...");
		return;
	}
	DeputyPart *pPart = dynamic_cast<DeputyPart*>(pPlayer->GetPart(PART_DEPUTY));
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] CL_UnionFightUpVerifyRsp parse..nullptr == pPart... failed...");
		return;
	}
	//pPart->MakeUpgrade_VerifyReturn(rsp);
}

void LogicUnionModule::CLUnionLeaderFacade(RECV_PACKAGE &package)
{
	CL_UnionLeaderFacadeNotify notify;
	if (!notify.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionLeaderFacadeNotify parse failed...");
		return;
	}
	uint32_t sceneId = notify.scene_id();
	CharOutward *pNpcFacade = nullptr;
	if (notify.has_facade())
	{
		pNpcFacade = notify.mutable_facade();
	}
	g_GetDuplicateMgr()->OnUnionLeaderFacade(sceneId, pNpcFacade);
}

void LogicUnionModule::CLUnionDungeonClose(RECV_PACKAGE &package)
{
	CL_UnionDungeonCloseRsp rsp;
	if (!rsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] CL_UnionDungeonCloseRsp parse failed...");
		return;
	}
	uint32_t unionId = rsp.union_id();
	uint32_t sceneId = rsp.scene_id();
	g_GetDuplicateMgr()->OnUnionDungeonClose(unionId, sceneId);
}